package ch.zbw.pra.sysventory.business.businessObject.scan;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.EnumVariant;
import com.jacob.com.Variant;

import ch.zbw.pra.sysventory.model.Printer;

/**
 * Gibt alle Installierten Printer mittels WMI Schnittstelle auf einem bestimmten Host zurück
 * 
 * @author Ralph Koster
 */
public class ScanPrinterBusinessObject implements Serializable {

	private static final long serialVersionUID = 7975139667109598945L;
	private static Logger LOG = LoggerFactory.getLogger(ScanPrinterBusinessObject.class);

	private String printerName;
	private String printerDriverName;
	private String printerDriverVersion;

	public ScanPrinterBusinessObject() {
		
	}

	public List<Printer> getPrinterFromHost(String host) {

		List<Printer> printers = new ArrayList<Printer>();
		List<String> pPrinter = new ArrayList<String>();
		List<String> pDriver = new ArrayList<String>();

		String connectStr = String.format("winmgmts:\\\\%s\\root\\CIMV2", host);
		String query = "SELECT * FROM Win32_Printer";

		try {
			ActiveXComponent axWMI = new ActiveXComponent(connectStr);
			Variant vCollection = axWMI.invoke("ExecQuery", new Variant(query));

			EnumVariant enumVariant = new EnumVariant(vCollection.toDispatch());
			Dispatch item = null;
			while (enumVariant.hasMoreElements()) {
				item = enumVariant.nextElement().toDispatch();
				// Dispatch.call returns a Variant which we can convert to a java form.
				String printerName = Dispatch.call(item, "Name").toString();
				String printerDriverName = Dispatch.call(item, "DriverName").toString();

				pPrinter.add(printerName);
				pPrinter.add(printerDriverName);
			}

			query = "SELECT * FROM Win32_PrinterConfiguration";
			vCollection = axWMI.invoke("ExecQuery", new Variant(query));
			enumVariant = new EnumVariant(vCollection.toDispatch());
			item = null;
			while (enumVariant.hasMoreElements()) {
				item = enumVariant.nextElement().toDispatch();
				// Dispatch.call returns a Variant which we can convert to a java form.

				String printerDriverVersion = Dispatch.call(item, "DriverVersion").toString();
				String printerCaptionVersion = Dispatch.call(item, "Caption").toString();

				pDriver.add(printerDriverVersion);
				pDriver.add(printerCaptionVersion);
			}

			for (int i = 0; i < pPrinter.size(); i = i + 2) {
				printerName = pPrinter.get(i);
				printerDriverName = pPrinter.get(i + 1);
				printerDriverVersion = pDriver.get(i + 1);

				LOG.debug("Printer found: " + printerName + " Treiber: " + printerDriverName
						+ " Treiberversion: " + printerDriverVersion);
				
				Printer printer = new Printer(printerName, printerDriverName, printerDriverVersion);

				printers.add(printer);
			}
		} catch (Exception e) {
			LOG.debug("Failed to load printers on host: " + host);
			LOG.error(e.toString());
		}

		return printers;

	}
	
}
